﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace LINQ
{
    class Program
    {
        static void Main(string[] args)
        {
            //Example();
            //LinqSort();
            //CountWords();
        }

        /// <summary>
        /// 简单方法展示 from where select
        /// </summary>
        public static void Example()
        {
            int[] numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };

            //延迟执行 知道下面的 foreach访问的时候才开始执行查询
            var numQuery =
                from num in numbers
                where (num % 2) == 0
                select num;

            //立即执行 使用后ToArray 或者 Tolist
            var numQueryNow =
             (from num in numbers
              where (num % 2) == 0
              select num).ToArray();

            foreach (var item in numQuery)
            {
                Console.Write("{0,1}\t", item);
            }
        }

        /// <summary>
        /// 排序 orderby
        /// </summary>
        public static void LinqSort()
        {
            string[] fruits = { "cherry", "apple", "blueberry" };

            //排序A-Z   orderby XX //"ascending" is default 
            var OrderbyAscending =
                   from num in fruits
                   orderby num
                   select num;

            //排序Z-A  orderby XX descending
            var OrderbyDescending =
                from num in fruits
                orderby num descending
                select num;

            foreach (var item in OrderbyDescending)
            {
                Console.WriteLine("{0,1}", item);
            }
        }

        /// <summary>
        /// 演示利用Linq对某个词在字符串中出现次数进行技术
        /// </summary>
        public static void CountWords()
        {
            string text = @"Historically, the world of data and the world of objects" +
              @" have not been well integrated. Programmers work in C# or Visual Basic" +
              @" and also in SQL or XQuery. On the one side are concepts such as classes," +
              @" objects, fields, inheritance, and .NET APIs. On the other side" +
              @" are tables, columns, rows, nodes, and separate languages for dealing with" +
              @" them. Data types often require translation between the two worlds; there are" +
              @" different standard functions. Because the object world has no notion of query, a" +
              @" query can only be represented as a string without compile-time type checking or" +
              @" IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to" +
              @" objects in memory is often tedious and error-prone.";

            string searchTerm = "data";

            //Convert the string into an array of words  
            string[] source = text.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries);

            // Create the query.  Use ToLowerInvariant to match "data" and "Data"
            var matchQuery = from word in source
                             where word.ToLowerInvariant() == searchTerm.ToLowerInvariant()
                             select word;

            // Count the matches, which executes the query.  
            int wordCount = matchQuery.Count();
            Console.WriteLine("{0} occurrences(s) of the search term \"{1}\" were found.", wordCount, searchTerm);

            // Keep console window open in debug mode  
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }
}


/// <summary>
/// 示例对学生的姓氏进行主要排序，然后对其名字进行次要排序。
/// </summary>
class OrderbySample2
{
    // The element type of the data source.
    public class Student
    {
        public string First { get; set; }
        public string Last { get; set; }
        public int ID { get; set; }
    }

    public static List<Student> GetStudents()
    {
        // Use a collection initializer to create the data source. Note that each element
        //  in the list contains an inner sequence of scores.
        List<Student> students = new List<Student>
        {
           new Student {First="Svetlana", Last="Omelchenko", ID=111},
           new Student {First="Claire", Last="O'Donnell", ID=112},
           new Student {First="Sven", Last="Mortensen", ID=113},
           new Student {First="Cesar", Last="Garcia", ID=114},
           new Student {First="Debra", Last="Garcia", ID=115}
        };

        return students;
    }
    static void Main(string[] args)
    {
        // Create the data source.
        List<Student> students = GetStudents();

        // Create the query.
        IEnumerable<Student> sortedStudents =
            from student in students
            orderby student.Last ascending, student.First ascending
            select student;

        // Execute the query.
        Console.WriteLine("sortedStudents:");
        foreach (Student student in sortedStudents)
            Console.WriteLine(student.Last + " " + student.First);

        // Now create groups and sort the groups. The query first sorts the names
        // of all students so that they will be in alphabetical order after they are
        // grouped. The second orderby sorts the group keys in alpha order.
        var sortedGroups =
            from student in students
            orderby student.Last, student.First
            group student by student.Last[0] into newGroup
            orderby newGroup.Key
            select newGroup;

        // Execute the query.
        Console.WriteLine(Environment.NewLine + "sortedGroups:");
        foreach (var studentGroup in sortedGroups)
        {
            Console.WriteLine(studentGroup.Key);
            foreach (var student in studentGroup)
            {
                Console.WriteLine("   {0}, {1}", student.Last, student.First);
            }
        }

        // Keep the console window open in debug mode
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
